#include "factory.h"

int exit_pipeFd[2];
void exit_sigfunc(int signum)
{
    printf("要有序退出了\n");
    write(exit_pipeFd[1],"1",1);    
}

int main(int argc,char *argv[])
{
    ARGS_CHECK(argc,4);
    //有序退出
    pipe(exit_pipeFd);
    if(fork())
    {
        //父进程专门负责有序退出
        signal(SIGUSR1,exit_sigfunc);
        wait(NULL);
        exit(0);
    }

    //子进程
    int threadNum=atoi(argv[3]);
#ifdef DEBUG
    printf("threadNum =%d\n",threadNum);
#endif
    factory_t f;
    factoryInit(&f,threadNum);//初始化工厂
    factoryStart(&f);//启动子线程
    int sock_fd,new_fd;
    tcp_init(argv[1],argv[2],&sock_fd);//网络初始化
    struct sockaddr_in clientAddr;
    socklen_t addrLen;
    taskQueue_t *pQue=&f.taskQueue;//方便使用
    //注册监控sock_fd
    int epfd=epoll_create(1);
    epoll_add(epfd,sock_fd);
    //注册监控退出管道的读端
    epoll_add(epfd,exit_pipeFd[0]);

    int ready_fd_num,i,j;
    struct epoll_event evs[2];
    while(1)
    {
        ready_fd_num=epoll_wait(epfd,evs,2,-1);
        for(i=0;i<ready_fd_num;i++)
        {
            if(evs[i].data.fd==sock_fd)
            {
                addrLen=sizeof(clientAddr);
                new_fd=accept(sock_fd,(struct sockaddr *)&clientAddr,&addrLen);
                ERROR_CHECK(new_fd,-1,"accept");
#ifdef DEBUG
                printf("主线程将任务放入队列\n");
#endif
                taskEnQueue(pQue,new_fd);
                pthread_cond_signal(&f.cond);//唤醒子线程
            }else if(evs[i].data.fd==exit_pipeFd[0])
            {
#ifdef DEBUG
                printf("线程池开始退出\n");
#endif
                close(sock_fd);
                pthread_mutex_lock(&pQue->mutex);
                f.exitFlag=1;//标记退出
                pthread_mutex_unlock(&pQue->mutex);
                for(j=0;j<threadNum;j++)
                {
                    pthread_cond_signal(&f.cond);//全部唤醒                   
                }
                for(j=0;j<threadNum;j++)
                {
                    pthread_join(f.thidArr[j],NULL);                    
                }
                printf("线程池退出成功\n");
                exit(0);
            }
        }
    }
    return 0;
}